package ex03.connector.http;

import org.apache.catalina.util.ParameterMap;
import org.apache.catalina.util.RequestUtil;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @packgeName: ex03.connector.http
 * @ClassName: HttpRequest
 * @copyright: CopyLeft
 * @description:<描述>
 * @author: lili
 * @date: 2017/8/11-17:18
 * @version: 1.0
 * @since: JDK 1.8
 */
public class HttpRequest implements HttpServletRequest {

    private String contentType;
    private int contentLength;
    private InetAddress inetAddress;
    private InputStream input;
    private String method;
    private String protocol;
    private String queryString;
    private String requestURI;
    private String serverName;
    private int serverPort;
    private Socket socket;
    private boolean requestedSessionCookie;
    private String requestedSessionId;
    private boolean requestedSessionURL;

    protected HashMap attributes = new HashMap();

    protected String authorization = null;

    protected String contextPath = "";

    protected ArrayList cookies = new ArrayList();

    protected static ArrayList empty = new ArrayList();

    protected SimpleDateFormat formats[] = {
            new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",Locale.US),
            new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz",Locale.US),
            new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy",Locale.US)
    };



    protected HashMap headers = new HashMap();

    protected ParameterMap parameters = null;

    protected boolean parsed = false;

    protected String pathInfo = null;

    protected BufferedReader reader = null;

    protected ServletInputStream stream = null;


    public void addHeader(String name, String value) {

        name = name.toLowerCase();
        synchronized (headers){
            ArrayList values = (ArrayList) headers.get(name);
            if(values == null){
                values = new ArrayList();
                headers.put(name, values);
            }
            values.add(value);
        }
    }

    public void addCookie(Cookie cookie){
        synchronized (cookies){
            cookies.add(cookie);
        }
    }

    protected void parseParameters(){

        if(parsed) {
            return;
        }

        ParameterMap results = parameters;

        if(results==null){
            results = new ParameterMap();
        }
        results.setLocked(false);
        String encoding = getCharacterEncoding();
        if (encoding == null) {
            encoding = "ISO-8859-1";
        }
        String queryString = getQueryString();
        try {
            RequestUtil.parseParameters(results,queryString,encoding);
        } catch (UnsupportedEncodingException e) {
            //这是不处理的意思？
            ;
        }

        String contentType = getContentType();
        if (contentType == null) {
            contentType = "";
        }
        int semicolon = contentType.indexOf(";");
        if(semicolon >= 0){
            contentType = contentType.substring(0,semicolon).trim();
        }else{
            contentType = contentType.trim();
        }

        if("POST".equals(getMethod())
                && (getContentLength()>0)
                && "application/x-www-form-urlencoded".equals(contentType)) {
            try{
                int max = getContentLength();
                int len = 0;
                byte buf[] = new byte[getContentLength()];
                ServletInputStream is = getInputStream();
                while(len < max){
                    int next = is.readLine(buf, len,max-len);
                    if(next<0){
                        break;
                    }
                    len+=next;
                }
                is.close();
                if(len < max){
                    throw new RuntimeException("Content length mismatch");
                }
                RequestUtil.parseParameters(results,buf,encoding);
            }catch (UnsupportedEncodingException ue){
                ;
            }catch (IOException e){
                throw new RuntimeException("Content read fail...");
            }

            results.setLocked(true);
            parsed = true;
            parameters = results;
        }


    }




    public void setMethod(String method) {
        this.method = method;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }

    public void setInetAddress(InetAddress inetAddress) {
        this.inetAddress = inetAddress;
    }

    public void setInput(InputStream input) {
        this.input = input;
    }

    public void setRequestURI(String requestURI) {
        this.requestURI = requestURI;
    }

    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    public void setServerPort(int serverPort) {
        this.serverPort = serverPort;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public void setAttributes(HashMap attributes) {
        this.attributes = attributes;
    }

    public void setAuthorization(String authorization) {
        this.authorization = authorization;
    }

    public void setContextPath(String contextPath) {
        this.contextPath = contextPath;
    }

    public void setCookies(ArrayList cookies) {
        this.cookies = cookies;
    }

    public static void setEmpty(ArrayList empty) {
        HttpRequest.empty = empty;
    }

    public void setFormats(SimpleDateFormat[] formats) {
        this.formats = formats;
    }

    public void setHeaders(HashMap headers) {
        this.headers = headers;
    }

    public void setParameters(ParameterMap parameters) {
        this.parameters = parameters;
    }

    public void setParsed(boolean parsed) {
        this.parsed = parsed;
    }

    public void setPathInfo(String pathInfo) {
        this.pathInfo = pathInfo;
    }

    public void setReader(BufferedReader reader) {
        this.reader = reader;
    }

    public void setStream(ServletInputStream stream) {
        this.stream = stream;
    }

    public void setRequestedSessionCookie(boolean requestedSessionCookie) {
        this.requestedSessionCookie = requestedSessionCookie;
    }

    public void setRequestedSessionId(String requestedSessionId) {
        this.requestedSessionId = requestedSessionId;
    }

    public void setRequestedSessionURL(boolean requestedSessionURL) {
        this.requestedSessionURL = requestedSessionURL;
    }

    public HttpRequest(InputStream input) {
        this.input = input;
    }

    @Override
    public String getAuthType() {
        return null;
    }

    @Override
    public Cookie[] getCookies() {
        return new Cookie[0];
    }

    @Override
    public long getDateHeader(String name) {
        return 0;
    }

    @Override
    public String getHeader(String name) {
        return null;
    }

    @Override
    public Enumeration getHeaders(String name) {
        return null;
    }

    @Override
    public Enumeration getHeaderNames() {
        return null;
    }

    @Override
    public int getIntHeader(String name) {
        return 0;
    }

    @Override
    public String getMethod() {
        return null;
    }

    @Override
    public String getPathInfo() {
        return null;
    }

    @Override
    public String getPathTranslated() {
        return null;
    }

    @Override
    public String getContextPath() {
        return null;
    }

    @Override
    public String getQueryString() {
        return null;
    }

    @Override
    public String getRemoteUser() {
        return null;
    }

    @Override
    public boolean isUserInRole(String role) {
        return false;
    }

    @Override
    public Principal getUserPrincipal() {
        return null;
    }

    @Override
    public String getRequestedSessionId() {
        return null;
    }

    @Override
    public String getRequestURI() {
        return null;
    }

    @Override
    public StringBuffer getRequestURL() {
        return null;
    }

    @Override
    public String getServletPath() {
        return null;
    }

    @Override
    public HttpSession getSession(boolean create) {
        return null;
    }

    @Override
    public HttpSession getSession() {
        return null;
    }

    @Override
    public boolean isRequestedSessionIdValid() {
        return false;
    }

    @Override
    public boolean isRequestedSessionIdFromCookie() {
        return false;
    }

    @Override
    public boolean isRequestedSessionIdFromURL() {
        return false;
    }

    @Override
    public boolean isRequestedSessionIdFromUrl() {
        return false;
    }

    @Override
    public Object getAttribute(String name) {
        return null;
    }

    @Override
    public Enumeration getAttributeNames() {
        return null;
    }

    @Override
    public String getCharacterEncoding() {
        return null;
    }

    @Override
    public void setCharacterEncoding(String env) throws UnsupportedEncodingException {

    }

    @Override
    public int getContentLength() {
        return 0;
    }

    @Override
    public String getContentType() {
        return null;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return null;
    }

    @Override
    public String getParameter(String name) {
        return null;
    }

    @Override
    public Enumeration getParameterNames() {
        return null;
    }

    @Override
    public String[] getParameterValues(String name) {
        return new String[0];
    }

    @Override
    public Map getParameterMap() {
        return null;
    }

    @Override
    public String getProtocol() {
        return null;
    }

    @Override
    public String getScheme() {
        return null;
    }

    @Override
    public String getServerName() {
        return null;
    }

    @Override
    public int getServerPort() {
        return 0;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return null;
    }

    @Override
    public String getRemoteAddr() {
        return null;
    }

    @Override
    public String getRemoteHost() {
        return null;
    }

    @Override
    public void setAttribute(String name, Object o) {

    }

    @Override
    public void removeAttribute(String name) {

    }

    @Override
    public Locale getLocale() {
        return null;
    }

    @Override
    public Enumeration getLocales() {
        return null;
    }

    @Override
    public boolean isSecure() {
        return false;
    }

    @Override
    public RequestDispatcher getRequestDispatcher(String path) {
        return null;
    }

    @Override
    public String getRealPath(String path) {
        return null;
    }

    @Override
    public int getRemotePort() {
        return 0;
    }

    @Override
    public String getLocalName() {
        return null;
    }

    @Override
    public String getLocalAddr() {
        return null;
    }

    @Override
    public int getLocalPort() {
        return 0;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }
}
